require 'MVVM.Sources.View.Adaptor'

ToggleGroupListAdaptor = class('ToggleGroupListAdaptor', Adaptor)

--[[
    @desc: 动态生成的ToggleGroup，支持viewmodel接入
    author:shengjiayang
    time:2019-12-12 19:41:19
    --@gameObject:列表父物体
	--@propertyName:viewmodel列表
	--@prefab:生成toggle预制体
	--@ToggleFater:togglegroup物体
	--@indexName:index property
	--@_viewCallBack:回调
	--@binder: Binder
    @return:adaptor
]]
function ToggleGroupListAdaptor:ctor(gameObject, propertyName, prefab, ToggleFater,indexName,_viewCallBack, binder)--这里不管理prefab释放，谁使用这个谁管理prefab的释放
    self.prefab = prefab
    self.ObjList = {}
    self.ToggleFater = ToggleFater:GetComponent("ToggleGroup")
    self.component = gameObject:GetComponent('RectTransform')
    self:BindProperty(propertyName, binder)
    binder:AddEx(propertyName,
        function(viewModel) self:OnAdd(viewModel) end,
        function(index, viewModel) self:OnInsert(index, viewModel) end,
        function(index) self:OnRemove(index) end)

    binder:RegisterEvent(function(viewModel, property)
        for i = 1, #self.ObjList do
            local toggle = self.ObjList[i]:GetComponent('Toggle')
            toggle.onValueChanged:AddListener(function(isOn)
                if isOn then
                    property.Value = i
                end
            end)
        end
    end, function()
        for i = 1, #self.ObjList do
            local toggle = self.ObjList[i]:GetComponent('Toggle')
            toggle.onValueChanged:RemoveAllListeners()
        end
    end, indexName)
    
    binder:Add(indexName,function(oldValue,newValue)
        if newValue == nil or oldValue == newValue then
            return
        end
    
        if self.ObjList[oldValue] then
            local spine = self.ObjList[oldValue].transform:Find('Checked/Spine')
            if spine then
                spine.gameObject:SetActive(false)
            end
        end
    
        if self.ObjList[newValue] then
            self.ObjList[newValue]:GetComponent('Toggle').isOn = true
            local spine = self.ObjList[newValue].transform:Find('Checked/Spine')
            if spine then
                spine.gameObject:SetActive(true)
            end
            if _viewCallBack ~= nil and self.ObjList[oldValue] ~= nil and self.ObjList[newValue] then
                _viewCallBack(oldValue,newValue,self.ObjList[oldValue].transform,self.ObjList[newValue].transform)
                AudioManager.PlaySound('SoundEffect/new_tab_click')
            end
        end
    end)
end

function ToggleGroupListAdaptor:GetPrefab(viewModel)
    if type(self.prefab) == 'function' then
        return self.prefab(viewModel)
    else
        return self.prefab
    end
end

function ToggleGroupListAdaptor:OnViewModelValueChanged(oldValue, newValue)
    if newValue == nil then
        return
    end

    local childCount = self.component.childCount
    local newCount = #newValue

    if type(self.prefab) == 'function' then--这种用函数生成的prefab内部完全没办法管理，只能全部删掉重新生成;使用Animation的这种为了美观要所有东西删掉重新生成
        for i = childCount - 1, 0, -1 do
            local go = self.component:GetChild(i).gameObject
            go.transform:SetParent(nil)
            GameObject.Destroy(go)
        end
        self.ObjList = {}
        for i, viewModel in pairs(newValue) do
            local go = GameObject.Instantiate(self:GetPrefab(viewModel))
            go.transform:GetComponent('Toggle').group = self.ToggleFater
            table.insert( self.ObjList , go )
            go.transform:SetParent(self.component, false)
        end
    else
        if childCount < newCount then
            for i = childCount + 1, newCount do
                local go = GameObject.Instantiate(self:GetPrefab(newValue[i]))
                go.transform:GetComponent('Toggle').group = self.ToggleFater
                table.insert( self.ObjList , go )
                go.transform:SetParent(self.component, false)
            end
        elseif childCount > newCount then
            for i, viewModel in pairs(newValue) do
                local go = GameObject.Instantiate(self:GetPrefab(viewModel))
                go.transform:GetComponent('Toggle').group = self.ToggleFater
                table.insert( self.ObjList , go )
                go.transform:SetParent(self.component, false)
            end
        end
    end

    for i, viewModel in pairs(newValue) do
        local go = self.component:GetChild(i - 1).gameObject
        local view = GetLuaObject(go)
        if view then
            view:Set_BindingContext(viewModel)
        end

        UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(go.transform)
    end
    UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(self.component)
end

function ToggleGroupListAdaptor:OnAdd(viewModel)
    local go = GameObject.Instantiate(self:GetPrefab(viewModel))
    go.transform:GetComponent('Toggle').group = self.ToggleFater
    table.insert( self.ObjList , go )

    UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(go.transform)
    go.transform:SetParent(self.component, false)
    go.transform:SetAsLastSibling()
    local view = GetLuaObject(go)
    if view then
        view:Set_BindingContext(viewModel)
    end

    UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(self.component)
end

function ToggleGroupListAdaptor:OnInsert(index, viewModel)
    local go = GameObject.Instantiate(self:GetPrefab(viewModel))
    go.transform:GetComponent('Toggle').group = self.ToggleFater
    table.insert( self.ObjList , go )

    UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(go.transform)
    local beforeHeight = self.component.rect.height
    go.transform:SetParent(self.component, false)
    go.transform:SetSiblingIndex(index - 1)
    local view = GetLuaObject(go)
    if view then
        view:Set_BindingContext(viewModel)
    end

    UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(self.component)
    local afterHeight = self.component.rect.height
    local displacement = afterHeight - beforeHeight


    local anchoredPosition = self.component.anchoredPosition
    anchoredPosition.y = anchoredPosition.y + displacement
    self.component.anchoredPosition = anchoredPosition

end

function ToggleGroupListAdaptor:OnRemove(index)
    local trans = self.component.transform:GetChild(index - 1)
    table.remove(self.ObjList,index)
    trans:SetParent(nil)
    GameObject.Destroy(trans.gameObject)
end